#pragma once
#include <string>
#include <vector>
#include "HashRoutine.h"

#define OPT_ASIS 0x01
#define OPT_UPPERCASE 0x02
#define OPT_REVERSE 0x04
#define OPT_LOWERCASE 0x08
#define OPT_TITLECASE 0x10
#define OPT_LEET	0x20
#define OPT_CASEPERM 0x40
#define OPT_ONENUMBER 0x80
#define OPT_TWONUMBER 0x100
#define OPT_THREENUMBER 0x200
#define OPT_TRYNUMATSTART 0x400
#define OPT_ENABLESALT	0x800

using namespace std;

typedef vector<string> WORDLIST;
typedef vector<unsigned char *> HASHLIST;
typedef void (*CBPASSCRACKED)(char *pHash, string sPlain);

class CDictionaryCracker
{
private:
	void StringToUpper(char *str, int nLen);
	void StringToLower(char *str, int nLen);
	void ReverseString(char *str, int nLen);
	int m_nPassTried;
	WORDLIST *m_vWordList;
	HASHLIST *m_vHashList;
	HASHROUTINE m_pHashFunc;
	CBPASSCRACKED m_pPassCracked;
	int m_nHashLen;
	
	void CheckPassword(unsigned char *pHash, char *pWord, int nLen);
	void Bin2Hash(unsigned char* pHash, int nHashLen, string &sHash)
	{
		int i;
		char *hash = new char[nHashLen*2];
		for (i = 0; i < nHashLen; i++)
		{
			sprintf(hash + i*2, "%02x", (unsigned int)pHash[i]);
		}
		sHash = string((char*)hash, nHashLen * 2);
		delete hash;
	}

public:
	CDictionaryCracker(void);
	~CDictionaryCracker(void);
	void SetDictionary(WORDLIST *vWordList);
	void SetHashList(HASHLIST *vHashList, int nHashLen, HASHROUTINE pHashFunc);
	void Start(CBPASSCRACKED pPassCracked, int nOptions);
	int GetPassTried() { return m_nPassTried; };
};
